<!DOCTYPE html>
<html>

<head>
  <title>Quarkus - Funqy HTTP Binding (Standalone)</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/funqy-http" />
  <meta property="og:title" content="Quarkus - Funqy HTTP Binding (Standalone)" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/funqy-http">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Quarkus - Funqy HTTP Binding (Standalone)</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#the-quickstart">The Quickstart</a></li>
<li><a href="#the-code">The Code</a></li>
<li><a href="#maven-dependencies">Maven Dependencies</a></li>
<li><a href="#build-project">Build Project</a></li>
<li><a href="#execute-funqy-http-functions">Execute Funqy HTTP functions</a></li>
<li><a href="#get-query-parameter-mapping">GET Query Parameter Mapping</a></li>
</ul></div>
    <div>
      <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>The guide walks through quickstart code to show you how you can deploy Funqy as a
standalone service and invoke on Funqy functions using HTTP.</p>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<i class="fa icon-warning" title="Warning"></i>
</td>
<td class="content">
The Funqy HTTP binding is not a replacement for REST over HTTP.  Because Funqy
needs to be portable across a lot of different protocols and function providers its HTTP binding
is very minimalistic and you will lose REST features like linking and the ability to leverage
HTTP features like cache-control and conditional GETs.  You may want to consider using Quarkus&#8217;s
JAX-RS, Spring MVC, or Vert.x Web Reactive Routes support instead, although Funqy will have less overhead
than these alternatives (except Vert.x which is still super fast).
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="prerequisites"><a class="anchor" href="#prerequisites"></a>Prerequisites</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To complete this guide, you need:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>less than 15 minutes</p>
</li>
<li>
<p>Read about <a href="funqy">Funqy Basics</a>.  This is a short read!</p>
</li>
<li>
<p>an IDE</p>
</li>
<li>
<p>JDK 1.8+ installed with <code>JAVA_HOME</code> configured appropriately</p>
</li>
<li>
<p>Apache Maven 3.6.2+</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="the-quickstart"><a class="anchor" href="#the-quickstart"></a>The Quickstart</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Clone the Git repository: <code>git clone <a href="https://github.com/quarkusio/quarkus-quickstarts.git" class="bare">https://github.com/quarkusio/quarkus-quickstarts.git</a></code>, or download an <a href="https://github.com/quarkusio/quarkus-quickstarts/archive/master.zip">archive</a>.</p>
</div>
<div class="paragraph">
<p>The solution is located in the <code>funqy-http-quickstart</code> <a href="https://github.com/quarkusio/quarkus-quickstarts/tree/master/funqy-quickstarts/funqy-http-quickstart">directory</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="the-code"><a class="anchor" href="#the-code"></a>The Code</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If you look at the Java code, you&#8217;ll see that there is no HTTP specific API.  Its just simple Java methods
annotated with <code>@Funq</code>.  Simple, easy, straightforward.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="maven-dependencies"><a class="anchor" href="#maven-dependencies"></a>Maven Dependencies</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To write Funqy HTTP functions, simply include the <code>quarkus-funqy-http</code> dependency into your Quarkus <code>pom.xml</code> file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
    &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
    &lt;artifactId&gt;quarkus-funqy-http&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="build-project"><a class="anchor" href="#build-project"></a>Build Project</h2>
<div class="sectionbody">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">mvn clean quarkus:dev</code></pre>
</div>
</div>
<div class="paragraph">
<p>This starts your functions in Quarkus dev mode.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="execute-funqy-http-functions"><a class="anchor" href="#execute-funqy-http-functions"></a>Execute Funqy HTTP functions</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The URL path to execute a function is the function name.  For example if your function name is <code>foo</code> then the URL path
to execute the function would be <code>/foo</code>.</p>
</div>
<div class="paragraph">
<p>The HTTP POST or GET methods can be used to invoke on a function.  The return value of the function
is marshalled to JSON using the Jackson JSON library.  Jackson annotations can be used.  If your function
has an input parameter, a POST invocation must use JSON as the input type.  Jackson is also used here for unmarshalling.</p>
</div>
<div class="paragraph">
<p>You can invoke the <code>hello</code> function defined in <a href="https://github.com/quarkusio/quarkus-quickstarts/tree/master/funqy-quickstarts/funqy-http-quickstart/src/main/java/org/acme/funqy/PrimitiveFunctions.java">PrimitiveFunctions.java</a>
by pointing your browser to <a href="http://localhost:8080/hello" class="bare">http://localhost:8080/hello</a></p>
</div>
<div class="paragraph">
<p>Invoking the other functions in the quickstart requires an HTTP POST.
To execute the <code>greet</code> function defined in <a href="https://github.com/quarkusio/quarkus-quickstarts/tree/master/funqy-quickstarts/funqy-http-quickstart/src/main/java/org/acme/funqy/GreetingFunction.java">GreetingFunction.java</a>
invoke this curl script.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">curl "http://localhost:8080/greet" \
-X POST \
-H "Content-Type: application/json" \
-d '{"name":"Bill"}'</code></pre>
</div>
</div>
<div class="paragraph">
<p>Primitive types can also be passed as input using the standard JSON mapping for them.
To execute the <code>toLowerCase</code> function defined in <a href="https://github.com/quarkusio/quarkus-quickstarts/tree/master/funqy-quickstarts/funqy-http-quickstart/src/main/java/org/acme/funqy/PrimitiveFunctions.java">PrimitiveFunctions.java</a>
invoke this curl script:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">curl "http://localhost:8080/toLowerCase" \
-X POST \
-H "Content-Type: application/json" \
-d '"HELLO WORLD"'</code></pre>
</div>
</div>
<div class="paragraph">
<p>To execute the <code>double</code> function defined in <a href="https://github.com/quarkusio/quarkus-quickstarts/tree/master/funqy-quickstarts/funqy-http-quickstart/src/main/java/org/acme/funqy/PrimitiveFunctions.java">PrimitiveFunctions.java</a>
invoke this curl script:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">curl "http://localhost:8080/double" \
-X POST \
-H "Content-Type: application/json" \
-d '2'</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="get-query-parameter-mapping"><a class="anchor" href="#get-query-parameter-mapping"></a>GET Query Parameter Mapping</h2>
<div class="sectionbody">
<div class="paragraph">
<p>For GET requests, the Funqy HTTP Binding also has a query parameter mapping for function input parameters.
Only bean style classes and <code>java.util.Map</code> can be used for your input parameter.  For bean style
classes, query parameter names are mapped to properties on the bean class.  Here&#8217;s an example of a simple
<code>Map</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Funq
public String hello(Map&lt;String, Integer&gt; map) {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Key values must be a primitive type (except char) or <code>String</code>.  Values can be primitives (except char), <code>String</code>, <code>OffsetDateTime</code> or a complex
bean style class.  For the above example, here&#8217;s the corresponding curl request:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">curl "http://localhost:8080/a=1&amp;b=2"</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>map</code> input parameter of the <code>hello</code> function would have the key value pairs: <code>a</code>&#8594;1, <code>b</code>&#8594;2.</p>
</div>
<div class="paragraph">
<p>Bean style classes can also be use as the input parameter type.  Here&#8217;s an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">public class Person {
    String first;
    String last;

    public String getFirst() { return first; }
    public void setFirst(String first) { this.first = first; }
    public String getLast() { return last; }
    public void setLast(String last) { this.last = last; }
}

public class MyFunctions {
    @Funq
    public String greet(Person p) {
       return "Hello " + p.getFirst() + " " + p.getLast();
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Property values can be any primitive type except <code>char</code>. It can also be <code>String</code>, and <code>OffsetDateTime</code>.
<code>OffsetDateTime</code> query param values must be in ISO-8601 format.</p>
</div>
<div class="paragraph">
<p>You can invoke on this using an HTTP GET and query parameters:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">curl "http://localhost:8080/greet?first=Bill&amp;last=Burke"</code></pre>
</div>
</div>
<div class="paragraph">
<p>In the above request, the query parameter names are mapped to corresponding properties in the input class.</p>
</div>
<div class="paragraph">
<p>The input class can also have nested bean classes.  Expanding on the previous example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">public class Family {
    private Person dad;
    private Person mom;

    public Person getDad() { return dad; }
    public void setDad(Person dad) { this.dad = dad; }
    public Person getMom() { return mom; }
    public void setMom(Person mom) { this.mom = mom; }
}

public class MyFunctions {
    @Funq
    public String greet(Family family) {
       ...
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this case, query parameters for nested values use the <code>.</code> notation.  For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">curl "http://localhost:8080/greet?dad.first=John&amp;dad.last=Smith&amp;mom.first=Martha&amp;mom.last=Smith"</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>java.util.List</code> and <code>Set</code> are also supported as property values.  For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">public class Family {
    ...

    List&lt;String&gt; pets;
}

public class MyFunctions {
    @Funq
    public String greet(Family family) {
       ...
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>To invoke a GET request, just list the <code>pets</code> query parameter multiple times.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">curl "http://localhost:8080/greet?pets=itchy&amp;pets=scratchy"</code></pre>
</div>
</div>
<div class="paragraph">
<p>For more complex types, <code>List</code> and <code>Set</code> members must have an identifier in the
query parameter.  For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">public class Family {
    ...

    List&lt;Person&gt; kids;
}

public class MyFunctions {
    @Funq
    public String greet(Family family) {
       ...
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Each <code>kids</code> query parameter must identify the kid they are referencing so that
the runtime can figure out which
property values go to which members in the list.  Here&#8217;s the curl request:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">curl "http://localhost:8080/greet?kids.1.first=Buffy&amp;kids.2.first=Charlie"</code></pre>
</div>
</div>
<div class="paragraph">
<p>The above URL uses the value <code>1</code> and <code>2</code> to identity the target member of the list, but any unique
string can be used.</p>
</div>
<div class="paragraph">
<p>A property can also be a <code>java.util.Map</code>.  The key of the map can be any primitive type and <code>String</code>.
For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">public class Family {
    ...

    Map&lt;String, String&gt; address;
}

public class MyFunctions {
    @Funq
    public String greet(Family family) {
       ...
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The corresponding call would look like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">curl "http://localhost:8080/greet?address.state=MA&amp;address.city=Boston"</code></pre>
</div>
</div>
<div class="paragraph">
<p>If your <code>Map</code> value is a complex type, then just continue the notation by adding the property to set at the end.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">public class Family {
    ...

    Map&lt;String, Address&gt; addresses;
}

public class MyFunctions {
    @Funq
    public String greet(Family family) {
       ...
    }
}</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">curl "http://localhost:8080/greet?addresses.home.state=MA&amp;addresses.home.city=Boston"</code></pre>
</div>
</div>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
